package graphs;

import java.util.List;

/**
 * Interface for graph objects
 * @author Ballarini Robin, Chatelain Julie
 * @version 12/12/2013
 * @param <T> type of the element stored in edges
 * @param <E> type of the element stored in vertices
 */
public interface IGraph<T extends Comparable<T>,E> {
	
	/**
	 * Return an iterable collection of all the vertices of the graph.
	 * @return an iterable collection of vertices.
	 */
	 public Iterable<Vertex<T,E>> vertices();
	 
	 /**
	  * Return an iterable collection of all the edges of the graph.
	  * @return an iterable collection of edges.
	  */
	 public Iterable<Edge<T,E>> edges();
	 
	 /**
	  * Return an iterable collection of the edges incident upon vertex v.
	  * @param v the vertex
	  * @return an iterable collection of edges.
	  */
	 public Iterable<Edge<T,E>> incidentEdges(Vertex<T,E> v);
	 
	 /**
	  * Return the end vertex of edge e distinct from vertex v; 
	  * An error occurs if e is not incident on v.
	  * @throws GraphException when e is not incident to v or e is a loop edge
	  * @param v the vertex
	  * @param e the edge
	  * @return the end vertex
	  */
	 public Vertex<T,E> opposite(Vertex<T,E> v, Edge<T,E> e) throws GraphException;
	 
	 /**
	  * Return an array storing the end vertices of edge e.
	  * @param e the edge
	  * @return an array of the end vertices of e.
	  */
	 public List<Vertex<T,E>> endVertices(Edge<T,E> e);
	 
	 /**
	  * Test whether vertices v and w are adjacent.
	  * @param v a vertex
	  * @param w a vertex
	  * @return boolean whether or not v and w are adjacent
	  */
	 public boolean areAdjacent(Vertex<T,E> v, Vertex<T,E> w);
	 
	 /**
	  * Replace the element stored at vertex v with x.
	  * @param v the vertex
	  * @param x the new element of v
	  * @return the old element of v
	  */
	 public E replace (Vertex<T,E> v, E x);
	 
	 /**
	  * Replace the element stored at edge e with x.
	  * @param e the vertex
	  * @param x the new element of e
	  * @return the old element of e
	  */
	 public T replace (Edge<T,E> e, T x);
	 
	 /**
	  * Insert and return a new vertex storing element x.
	  * @param x the element of the new vertex.
	  * @return the new vertex.
	  */
	 public Vertex<T,E> insertVertex(E x);
	 
	 /**
	  * Insert and return a new undirected edge with 
	  * end vertices v and w storing element x.
	  * @param v a vertex
	  * @param w a vertex
	  * @param x the element of the new edge
	  * @return the new edge
	  */
	 public Edge<T,E> insertEdge(Vertex<T,E> v, Vertex<T,E> w, T x);
	 
	 /**
	  * Remove vertex v and all its incident edges and 
	  * return the element stored at v.
	  * @param v the vertex
	  * @return the element stored at v.
	  */
	 public E removeVertex(Vertex<T,E> v);
	 
	 /**
	  * Remove edge e and return the element stored at e.
	  * @param e the edge
	  * @return the element stored at e.
	  */
	 public T removeEdge(Edge<T,E> e);
}

